package com.itheima.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

//通知类，告诉spring在增强的前后需要做什么事
@Component
@Aspect   //代替：<aop:aspect ref="advice">，该类即是一个通知类也是一个切面类
public class Advice {
    //定义切入点表达式的方法,方法体不需要写任何内容，方法名就是切入点的id
    @Pointcut("execution(* com.itheima.service.impl.StudentServiceImpl.*(..))")
    public void pt(){}

    @Before("pt()")
    public void before(){
        //前置通知：开启事务
        System.out.println("前置通知：开启事务");
    }
    @AfterReturning("pt()")
    public void afterReturn(){
        //后置通知：提交事务
        System.out.println("后置通知：提交事务");
    }
    @AfterThrowing("pt()")
    public void afterThrowable(){
        //异常通知：回滚事务
        System.out.println("异常通知：回滚事务");
    }
    @After(("pt()"))
    public void after(){
        //最终通知：释放资源
        System.out.println("最终通知：" +
                "释放资源");
    }

    //@Around("pt()")
    public Object around(ProceedingJoinPoint pjp){

        Object result=null;
        try {
            Object[] args = pjp.getArgs();
            before();
            //执行目标方法
             result = pjp.proceed(args);
            //后置通知
            afterReturn();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            //异常通知
            afterThrowable();
        }finally {
            after();
        }
        return result;

    }

}
